package com.cloudspace.jindun.utils;

import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.cloudspace.jindun.JindunApp;
import com.cloudspace.jindun.R;
import com.cloudspace.jindun.callback.AudioSendCallback;
import com.cloudspace.jindun.callback.PlayFinishCallback;
import com.cloudspace.jindun.callback.StartRecordingCallback;
import com.cloudspace.jindun.log.APPLog;

import java.io.File;

import io.rong.imkit.RongIM;
import io.rong.imlib.IRongCallback;
import io.rong.imlib.RongIMClient;
import io.rong.imlib.model.Conversation;
import io.rong.message.VoiceMessage;

import static android.R.attr.max;


public class AudioManager {

    private MediaPlayer mediaPlayer;

    public static final String TAG = AudioManager.class.getSimpleName();

    private static AudioManager instance;
    private boolean recordSuccess;

    public synchronized static AudioManager getInstance() {
        if (instance == null) {
            instance = new AudioManager();
        }

        return instance;
    }

    private String filePath;
    private String FolderPath;

    private MediaRecorder mMediaRecorder;
    public static final int MAX_LENGTH = 1000 * 60;// 最大录音时长1000*60;

    public AudioManager() {
        this(Environment.getExternalStorageDirectory() + "/record/");
    }

    public AudioManager(String filePath) {
        if (TextUtils.isEmpty(filePath)){
            return;
        }

        File path = new File(filePath);
        if (!path.exists()) {
            path.mkdirs();
        }

        this.FolderPath = filePath;
    }

    private long startTime;
    private long endTime;

    public void checkRecordPermission(){
        if (mMediaRecorder == null) {
            mMediaRecorder = new MediaRecorder();
        }

        try {
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 设置麦克风
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

            String path = FileUtil.getLocalFileCachePath() + "/" + System.currentTimeMillis() + ".amr";

            mMediaRecorder.setOutputFile(path);
            mMediaRecorder.setMaxDuration(MAX_LENGTH);

            mMediaRecorder.prepare();
            mMediaRecorder.start();
        }catch (Exception e){

        }finally {
            try {
                mMediaRecorder.stop();
                mediaPlayer.release();
            }catch (Exception e){

            }
            mMediaRecorder = null;
        }
    }


    public void startRecord(StartRecordingCallback callback) {
        try {
            if (mMediaRecorder == null) {
                mMediaRecorder = new MediaRecorder();
            }

            recordSuccess = false;

            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 设置麦克风
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

            startTime = System.currentTimeMillis();
            filePath = FolderPath + TimeUtils.getNowTimeMills() + ".amr";

            mMediaRecorder.setOutputFile(filePath);
            mMediaRecorder.setMaxDuration(MAX_LENGTH);
            mMediaRecorder.prepare();
            mMediaRecorder.start();

            recordSuccess = true;
        } catch (Exception e) {
            APPLog.zxhLog(TAG + "startRecord failed!" + Log.getStackTraceString(e));
            try {
                if (callback != null){
                    callback.onFail();
                }
            }catch (Exception ee){
                APPLog.zxhLog(TAG + "startRecord finally failed!" + Log.getStackTraceString(ee));
            }
        }
    }

    public void stopRecord() {
        stopRecorder();

        if (recordSuccess){
            endTime = System.currentTimeMillis();
        }
    }

    private void stopRecorder() {
        if (mMediaRecorder == null){
            return;
        }
        try{
            mMediaRecorder.stop();
            mMediaRecorder.reset();
        }catch (Exception e){
            APPLog.zxhLog(TAG + "stopRecorder failed!" + Log.getStackTraceString(e));
        }
    }

    public void sendAudioFile(String targetId, boolean isUrgency, final AudioSendCallback callback) {
        if (!recordSuccess){
            APPLog.zxhLog(TAG + " sendAudioFile () record fail... return");
            return;
        }

        if (TextUtils.isEmpty(filePath)){
            APPLog.zxhLog(TAG + " audio file not exist... return");
            return;
        }

        APPLog.zxhLog(TAG + " targetId:" + targetId);
        if (endTime - startTime <= 10) {
            ToastMaker.showToastShort(JindunApp.getInstance().getResources().
                    getString(R.string.audio_too_short));
            return;
        }

        VoiceMessage voiceMessage = VoiceMessage.obtain(Uri.fromFile(new File(filePath)), (int) (endTime - startTime));
        if (isUrgency){
            voiceMessage.setExtra("isUrgency");
        }
        RongIM.getInstance().sendMessage(io.rong.imlib.model.Message.obtain(targetId,
                Conversation.ConversationType.GROUP,
                voiceMessage),
                (String) null,
                (String) null,
                new IRongCallback.ISendMessageCallback() {
                    public void onAttached(io.rong.imlib.model.Message message) {
                    }

                    public void onSuccess(io.rong.imlib.model.Message message) {
                        APPLog.zxhLog(TAG + " sendAudioFile:onSuccess");

                        resetState();
                        if (callback != null && message.getContent() != null) {
                            callback.success(message);
                        }
                    }

                    public void onError(io.rong.imlib.model.Message message, RongIMClient.ErrorCode errorCode) {
                        APPLog.zxhLog(TAG + " sendAudioFile:onError:" + errorCode);
                    }
                });
    }

    public void resetState() {
        startTime = 0;
        endTime = 0;
        recordSuccess = false;
        filePath = "";
    }

    /**
     * 处理语音消息
     *
     * @param voiceMessage
     */
    public void playVoiceMessage(VoiceMessage voiceMessage, PlayFinishCallback cb, boolean mute) {
        Uri uri = voiceMessage.getUri();

        APPLog.tagLog(TAG, "playVoiceMessage:" + uri);

        if (ObjUtil.isEmpty(uri)) {
            return;
        }

        playAudio(uri, cb, mute);
    }

    private boolean isPlaying;
    private boolean hasBeenSetMute = false;
    private int defaultVolum = 5;

    private void playAudio(Uri uri, final PlayFinishCallback cb, boolean mute) {
        if (mediaPlayer == null) {
            mediaPlayer = new MediaPlayer();
        }

        try {
            mediaPlayer.reset();

            mediaPlayer.setDataSource(JindunApp.getInstance(), uri);
            mediaPlayer.prepare();
            mediaPlayer.start();

            if (mute){
                android.media.AudioManager  mAudioManager = (android.media.AudioManager) JindunApp.getInstance().getSystemService(Context.AUDIO_SERVICE);

                int maxVolumn = mAudioManager.getStreamMaxVolume(android.media.AudioManager.STREAM_ALARM);
                if (defaultVolum < maxVolumn){
                    defaultVolum = maxVolumn;
                }

                hasBeenSetMute = true;
                mediaPlayer.setVolume(0, 0);
            }else if (hasBeenSetMute){
                //被设置为静音，要恢复音量
                mediaPlayer.setVolume(defaultVolum, defaultVolum);
                APPLog.zxhLog(TAG + " resume volume:" + max);
            }

            isPlaying = true;
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    playAudioFinish(cb);
                }
            });
        } catch (Exception e) {
            APPLog.zxhLog(TAG + " playAudio() error:" + Log.getStackTraceString(e));
            ToastMaker.showToastShort(R.string.play_fail);
            playAudioFinish(cb);
        }
    }

    private void playAudioFinish(PlayFinishCallback cb) {
        if (cb != null){
            cb.onComplete();
        }

        stopPlaying();
    }

    public boolean isPlaying(){
        return isPlaying;
    }

    private void stopPlaying() {
        try{
            isPlaying = false;

            if (mediaPlayer != null) {
                mediaPlayer.release();
                mediaPlayer = null;
            }
        }catch(Exception e){
            APPLog.zxhLog(TAG + " stopPlaying() error:" + Log.getStackTraceString(e));
        }
    }

    public boolean canSend() {
        return endTime - startTime >= 1000;
    }
}